package com.dushuren.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dushuren.project.common.ErrorCode;
import com.dushuren.project.exception.BusinessException;
import com.dushuren.project.mapper.UserMapper;
import com.dushuren.project.model.dto.UserGetRequest;
import com.dushuren.project.model.dto.UserRenewRequest;
import com.dushuren.project.model.entity.User;
import com.dushuren.project.model.enums.SuggestSearchSelectEnum;
import com.dushuren.project.model.vo.UserVo;
import com.dushuren.project.service.UserService;
import com.dushuren.project.utils.RedisUtils;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.util.Random;

import static com.dushuren.project.constant.RedisConstant.DUSHUREN;
import static com.dushuren.project.constant.RedisConstant.USER;
import static com.dushuren.project.constant.UserConstant.ADMIN_ROLE;
import static com.dushuren.project.constant.UserConstant.USER_LOGIN_STATE;

/**
* @author qieqie
* @description 针对表【user(用户)】的数据库操作Service实现
* @createDate 2022-10-12 17:02:28
*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {

  @Resource
  UserMapper userMapper;

  @Resource
  RedisUtils redisUtils;



  private static final String SALT = "dushuren";

  @Override
  public long userRegister(String userAccount, String userPassword, String checkPassword) {
	if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
	}

	if (userAccount.length() < 4 || userAccount.length() > 14) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户长度不符合");
	}
	if (userPassword.length() < 8 || checkPassword.length() < 8 || checkPassword.length() > 20 || userPassword.length() > 20) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码长度不符合");
	}
	//密码和校验密码相同
	if (!userPassword.equals(checkPassword)) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
	}
	synchronized (userAccount.intern()) {
	  // 账号不能重复
	  QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	  queryWrapper.eq("userAccount", userAccount);
	  Long count = userMapper.selectCount(queryWrapper);
	  if (count > 0) {
		throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
	  }
	  // 加密
	  String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
	  // 插入数据
	  User user = new User();
	  user.setUserAccount(userAccount);
	  user.setUserPassword(encryptPassword);
	  user.setUserName("一起开发" + new Random(10).nextInt() + user.getId());
	  user.setGender(0);
	  user.setAvatarUrl("");
	  user.setUserProfile("");
	  user.setEmail("");
	  boolean saveResult = this.save(user);
	  if (!saveResult) {
		throw new BusinessException(ErrorCode.SYSTEM_ERROR,"注册失败,数据库错误");
	  }
	  return user.getId();
	}
  }

  @Override
  public UserVo userLogin(String userAccount, String userPassword, HttpServletRequest request) {
	if (StringUtils.isAnyBlank(userAccount, userPassword)) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
	}
	if (userAccount.length() < 4 || userAccount.length() > 14) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号错误");
	}
	if (userPassword.length() < 8 || userPassword.length() > 20) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误");
	}
	// 加密
	String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	queryWrapper.eq("userAccount", userAccount);
	queryWrapper.eq("userPassword", encryptPassword);
	User user = userMapper.selectOne(queryWrapper);
	if (user == null) {
	  log.info("user login failed, userAccount cannot match userPassword");
	  throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误");
	}
	UserVo userVO = this.getSftUser(user);
	// 记录用户的登录态
	request.getSession().setAttribute(USER_LOGIN_STATE, userVO.getId());
	String storage = DUSHUREN + ":" +USER + ":" + userVO.getId();

	redisUtils.hashPutAll(storage, userVO);
	return userVO;
  }

  @Override
  public boolean userLogout(HttpServletRequest request) {
	UserVo userVo = this.getIsServletRequest(request);
	// 删除登入态
	request.getSession().removeAttribute(USER_LOGIN_STATE);
	redisUtils.remove(DUSHUREN + ":" +USER + ":" + userVo.getId());
	return true;
  }

  /**
   * 校验用户是否还存在 数据库中 》 为了
   */
  @Override
  public User getLoginUser(HttpServletRequest request) {
	// 先判断是否登录
	UserVo currentUserVo = this.getIsServletRequest(request);
	if (currentUserVo.getId() <= 0) {
	  throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
	}
	User user = new User();
	BeanUtils.copyProperties(currentUserVo, user);
	return user;
  }

  @Override
  public UserVo getSftUser(User user) {
	UserVo userVO = new UserVo();
	BeanUtils.copyProperties(user,userVO);
	return userVO;
  }

  /***
   * 通过id查询队伍信息
   * @param userGetId
   * @return
   */
  @Override
  public User getUser(UserGetRequest userGetId) {
	QueryWrapper<User> queryWrapper = new QueryWrapper<>();
	queryWrapper.select("userAccount", "userName", "avatarUrl", "gender", "userProfile", "phone", "email", "tags","userStatus","creditsNum");
	queryWrapper.eq("id", userGetId.getId());
	User user = userMapper.selectOne(queryWrapper);
	if (user == null) {
	  throw new BusinessException(ErrorCode.PARAMS_ERROR);
	}
	return user;
  }

  /***
   * 是否为管理员
   * @param request
   */
  public void isAdministrators(HttpServletRequest request) {

	UserVo attribute = getIsServletRequest(request);
	if (ADMIN_ROLE != attribute.getUserRole()) {
	  throw new BusinessException(ErrorCode.NO_AUTH);
	}
  }

  /***
   * 通过request 获取到 redis中的值
   * @param request
   * @return
   */
  public UserVo getIsServletRequest(HttpServletRequest request) {
	Long userId = (Long) request.getSession().getAttribute(USER_LOGIN_STATE);
	if (userId == null || userId <= 0){
	  throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
	}
	String storage = DUSHUREN + ":" +USER + ":" + userId;
	UserVo userVo = (UserVo)redisUtils.getHashPut(storage);
	userVo.setId(userId);
	return userVo;
  }

  @Override
  public Long renewUser(UserRenewRequest renewRequest, UserVo userVo) {
	UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
	UserVo renewUserVo = new UserVo();
	long result = 1L;
	// 用户昵称
	String userName = renewRequest.getUserName();
	if (!userVo.getUserName().equals(userName)) {
	  result = 0L;
	  updateWrapper.set("userName", userName);
	  renewUserVo.setUserName(userName);
	}
	// 用户介绍
	String userProfile = renewRequest.getUserProfile();
	if (!userVo.getUserProfile().equals(userProfile)) {
	  result = 0L;
	  updateWrapper.set("userProfile", userProfile);
	  renewUserVo.setUserProfile(userProfile);
	}
	// 用户性别
	Integer gender = renewRequest.getGender();
	if (!userVo.getGender().equals(gender)) {
	  result = 0L;
	  updateWrapper.set("gender", gender);
	  renewUserVo.setGender(gender);
	}
	// 用户邮箱
	String email = renewRequest.getEmail();
	if (!userVo.getEmail().equals(email)) {
	  result = 0L;
	  updateWrapper.set("email", email);
	  renewUserVo.setEmail(email);
	}
	// 用户头像
	String avatarUrl = renewRequest.getAvatarUrl();
	if (!userVo.getAvatarUrl().equals(avatarUrl)) {
	  result = 0L;
	  updateWrapper.set("avatarUrl", avatarUrl);
	  renewUserVo.setAvatarUrl(avatarUrl);
	}
	if (result == 0L) {
	  this.update(updateWrapper);
	  String storage = DUSHUREN + ":" +USER + ":" + userVo.getId();
	  redisUtils.hashPutAll(storage, renewUserVo);
	}
	return result;
  }

}




